import { openDB, IDBPDatabase, DBSchema, StoreNames, IDBPTransaction } from 'idb';
import { FileSystemEntry, FileVersion } from '../types';
import { FileChange, LcCommit } from '@/types/modules/editor/types/commit.type';
import { DiffService } from './DiffService';

interface ScriptResource {
  url: string;
  content: string;
  lastLoadTime: number;
  version?: string;
  dependencies?: string[];
}

interface VFSSchema extends DBSchema {
  files: {
    key: string;
    value: FileSystemEntry;
    indexes: { 'by-project': string };
  };
  changes: {
    key: number;
    value: FileChange<any>;
    indexes: {
      'by-path': string;
      'by-timestamp': number;
      'by-path-timestamp': [string, number];
    };
  };
  versions: {
    key: number;
    value: FileVersion;
    indexes: { 'by-path': string };
  };
  // branches: {
  //   key: string;
  //   value: LcBranch;
  //   indexes: { 'by-project': string };
  // };
  commits: {
    key: string;
    value: LcCommit;
    indexes: { 'by-branch': string };
  };
  // 新增：文件系统版本管理
  fsVersions: {
    key: string; // projectId
    value: {
      projectId: string;
      version: number;
      upgradeTime: number;
      previousVersion?: number;
    };
  };
}

interface GlobalSchema extends DBSchema {
  scripts: {
    key: string;
    value: ScriptResource;
    indexes: { 'by-url': string };
  };
}

// 快照间隔
const SNAPSHOT_INTERVAL = 10;

// 删除本地 LcCommit 类型定义，全部用 types/commit.type.ts 的定义

// 扩展 FileChange 类型
export interface VFSFileChange {
  id: number;
  action: 'add' | 'modify' | 'delete';
  path: string;
  version: number;
  type: 'snapshot' | 'patch';
  content?: string; // 仅snapshot有
  patch?: string; // 仅patch有
  baseVersion?: number; // patch指向最近快照
  timestamp: number;
  author?: string;
  // ...其它元信息
}

export class Storage {
  private db: IDBPDatabase<VFSSchema> | null = null;
  private projectId: string;
  private diffService: DiffService;
  private globalDb: IDBPDatabase<GlobalSchema> | null = null;
  private scriptCache: Map<string, ScriptResource> = new Map();

  constructor() {
    this.projectId = '';
    this.diffService = new DiffService();
  }

  async init(projectId: string) {
    this.projectId = projectId;
    this.db = await openDB<VFSSchema>(`vfs-${projectId}`, 3, {
      upgrade(db, oldVersion, newVersion) {
        console.log(`[VFS Storage] 数据库升级: ${oldVersion} -> ${newVersion}`);

        if (oldVersion < 1) {
          // 创建文件存储
          const filesStore = db.createObjectStore('files', { keyPath: 'path' });
          filesStore.createIndex('by-project', 'projectId');

          // 创建变更记录存储
          const changesStore = db.createObjectStore('changes', {
            keyPath: 'id',
            autoIncrement: true,
          });
          changesStore.createIndex('by-path', 'path');
          changesStore.createIndex('by-timestamp', 'timestamp');
          changesStore.createIndex('by-path-timestamp', ['path', 'timestamp']);

          // 创建版本存储
          const versionsStore = db.createObjectStore('versions', {
            keyPath: 'id',
            autoIncrement: true,
          });
          versionsStore.createIndex('by-path', 'path');

          // 创建分支存储
          // const branchesStore = db.createObjectStore('branches', { keyPath: 'name' });
          // branchesStore.createIndex('by-project', 'projectId');

          // 创建提交存储
          const commitsStore = db.createObjectStore('commits', { keyPath: 'id' });
          commitsStore.createIndex('by-branch', 'branch');
        }

        if (oldVersion < 2) {
          // 版本 2: 添加文件系统版本管理
          if (!db.objectStoreNames.contains('fsVersions')) {
            const fsVersionsStore = db.createObjectStore('fsVersions', { keyPath: 'projectId' });
            console.log('[VFS Storage] 创建文件系统版本管理表');
          } else {
            console.log('[VFS Storage] 文件系统版本管理表已存在');
          }
        }

        if (oldVersion < 3) {
          // 版本 3: 优化历史记录查询
          console.log('[VFS Storage] 升级到版本 3: 优化索引结构');

          // 由于 IndexedDB 的限制，我们不能在现有 store 上添加索引
          // 但我们可以在查询时使用优化策略，无需重建数据
          // 新的索引将在新项目或清空数据后生效

          console.log('[VFS Storage] 版本 3 升级完成 - 查询优化已启用');
        }
      },
    });
  }

  private async getDB(): Promise<IDBPDatabase<VFSSchema>> {
    if (this.db) {
      return this.db;
    }
    throw new Error('Database not initialized');
  }

  // 检查数据库是否已初始化
  isInitialized(): boolean {
    return !!this.db;
  }

  // 获取文件键
  private getFileKey(path: string): string {
    return `${this.projectId}:${path}`;
  }

  // 文件操作
  async getFile(path: string): Promise<FileSystemEntry | undefined> {
    if (!this.db) return undefined;

    const key = this.getFileKey(path);
    // console.log('key: ', key);
    const entry = await this.db.get('files', key);
    if (!entry) return undefined;

    if (path.endsWith('.css') && entry.stats?.isDocument) {
      entry.stats.isDocument = false;
    }

    return {
      path: path,
      content: entry.content,
      stats: entry.stats,
    };
  }

  async putFile(
    entry: FileSystemEntry,
    tx?: IDBPTransaction<VFSSchema, ['files'], 'readwrite'>,
  ): Promise<void> {
    if (!this.db) return;

    const fileEntry = {
      projectId: this.projectId,
      path: this.getFileKey(entry.path),
      content: entry.content,
      stats: entry.stats,
    };

    if (tx) {
      await tx.store.put(fileEntry);
    } else {
      const newTx = this.db.transaction('files', 'readwrite');
      try {
        await newTx.store.put(fileEntry);
        await newTx.done;
      } catch (error) {
        console.error('[VFS Storage] 文件导入失败:', entry.path, error);
        throw error;
      }
    }
  }

  async deleteFile(path: string): Promise<void> {
    if (!this.db) return;
    await this.db.delete('files', this.getFileKey(path));
  }

  // 获取文件的所有版本
  async getVersions(path: string): Promise<FileVersion[]> {
    const db = await this.getDB();
    const tx = db.transaction('versions', 'readonly');
    const store = tx.objectStore('versions');
    const index = store.index('by-path');
    return index.getAll(path);
  }

  async getVersion(id: number): Promise<FileVersion | undefined> {
    return this.db?.get('versions', id);
  }

  async getLatestVersion(path: string): Promise<FileVersion | undefined> {
    const versions = await this.getVersions(path);
    return versions.sort((a, b) => b.version - a.version)[0];
  }

  // 变更记录操作
  async addChange(
    path: string,
    content: string,
    prevContent: string,
    version: number,
    action: 'add' | 'modify' | 'delete',
    author?: string,
  ): Promise<VFSFileChange | undefined> {
    const db = await this.getDB();
    let change: Partial<VFSFileChange> = {
      path,
      version,
      action,
      timestamp: Date.now(),
      author,
    };

    if (version === 1 || version % SNAPSHOT_INTERVAL === 0) {
      change.type = 'snapshot';
      change.content = content;
    } else {
      try {
        change.type = 'patch';
        const patches = this.diffService.computeDiff(prevContent, content);
        change.patch = this.diffService.serializePatches(patches);

        // 修正 baseVersion：指向最近的 snapshot 的 version
        const allChanges = (await db.getAllFromIndex(
          'changes',
          'by-path',
          path,
        )) as unknown as VFSFileChange[];
        const lastSnapshot = [...allChanges].reverse().find((c) => c.type === 'snapshot');
        change.baseVersion = lastSnapshot ? lastSnapshot.version : 1;
      } catch (error) {
        console.error('[Storage] 计算差异失败:', error);
        // 如果计算差异失败，回退到存储完整内容
        change.type = 'snapshot';
        change.content = content;
      }
    }

    // 只存 VFSFileChange
    const key = await db.add('changes', change as any);
    change.id = Number(key);
    return change as VFSFileChange;
  }

  // 还原任意版本内容
  async restoreVersion(path: string, targetVersion: number): Promise<string | undefined> {
    const db = await this.getDB();
    // 1. 找到最近的快照
    const all = (await db.getAllFromIndex(
      'changes',
      'by-path',
      path,
    )) as unknown as VFSFileChange[];
    const snapshot = all
      .filter((c) => c.type === 'snapshot' && c.version <= targetVersion)
      .sort((a, b) => b.version - a.version)[0];
    if (!snapshot) return undefined;
    let content = snapshot.content;
    // 2. 获取patch链
    const patches = all
      .filter(
        (c) =>
          c.type === 'patch' && c.version > (snapshot.version ?? 0) && c.version <= targetVersion,
      )
      .sort((a, b) => a.version - b.version);
    // 3. 依次apply
    for (const patch of patches) {
      if (patch.patch) {
        content = this.diffService.applyDiff(
          content,
          this.diffService.deserializePatches(patch.patch),
        )[0];
      }
    }
    return content;
  }

  // 获取文件的所有变更记录
  async getChanges(
    path?: string,
    options?: {
      startTime?: number;
      endTime?: number;
      skip?: number;
      limit?: number;
      sortBy?: string;
      sortOrder?: 'asc' | 'desc';
    },
  ): Promise<FileChange<any>[]> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');

    const skip = options?.skip || 0;
    const limit = options?.limit || 50;
    const sortBy = options?.sortBy || 'timestamp';
    const sortOrder = options?.sortOrder || 'desc';

    // 优化：根据查询条件选择最佳索引和策略
    if (sortBy === 'timestamp' && !path) {
      // 最常见情况：按时间排序的全局查询，使用时间戳索引
      return this.getChangesByTimestamp(options, skip, limit, sortOrder as 'asc' | 'desc');
    } else if (path && sortBy === 'timestamp') {
      // 特定文件的时间排序查询，使用复合索引
      return this.getChangesByPathAndTimestamp(
        path,
        options,
        skip,
        limit,
        sortOrder as 'asc' | 'desc',
      );
    } else if (path) {
      // 特定文件查询，使用路径索引
      return this.getChangesByPath(path, options, skip, limit, sortOrder as 'asc' | 'desc');
    } else {
      // 其他情况，回退到原有逻辑（但限制扫描数量）
      return this.getChangesLegacy(path, options, skip, limit, sortOrder as 'asc' | 'desc');
    }
  }

  // 优化方法：使用时间戳索引进行全局查询
  private async getChangesByTimestamp(
    options?: {
      startTime?: number;
      endTime?: number;
    },
    skip: number = 0,
    limit: number = 50,
    sortOrder: 'asc' | 'desc' = 'desc',
  ): Promise<FileChange<any>[]> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');

    // 检查是否有时间戳索引
    if (store.indexNames.contains('by-timestamp')) {
      const index = store.index('by-timestamp');

      const results: FileChange<any>[] = [];
      let processed = 0;
      let skipped = 0;

      // 构建时间范围
      let range: IDBKeyRange | undefined;
      if (options?.startTime && options?.endTime) {
        range = IDBKeyRange.bound(options.startTime, options.endTime);
      } else if (options?.startTime) {
        range = IDBKeyRange.lowerBound(options.startTime);
      } else if (options?.endTime) {
        range = IDBKeyRange.upperBound(options.endTime);
      }

      // 使用索引游标，直接按时间排序
      const direction = sortOrder === 'desc' ? 'prev' : 'next';
      let cursor = await index.openCursor(range, direction);

      while (cursor && results.length < limit) {
        if (skipped < skip) {
          skipped++;
        } else {
          results.push(cursor.value);
        }
        cursor = await cursor.continue();
        processed++;

        // 防止无限循环，限制处理数量
        if (processed > (skip + limit) * 2) break;
      }

      return results;
    } else {
      // 回退到传统方法
      console.log('[VFS Storage] by-timestamp 索引不存在，使用传统查询方法');
      return this.getChangesLegacy(undefined, options, skip, limit, sortOrder);
    }
  }

  // 优化方法：使用复合索引查询特定文件的时间排序记录
  private async getChangesByPathAndTimestamp(
    path: string,
    options?: {
      startTime?: number;
      endTime?: number;
    },
    skip: number = 0,
    limit: number = 50,
    sortOrder: 'asc' | 'desc' = 'desc',
  ): Promise<FileChange<any>[]> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');

    // 检查是否有复合索引
    if (store.indexNames.contains('by-path-timestamp')) {
      const index = store.index('by-path-timestamp');

      const results: FileChange<any>[] = [];
      let processed = 0;
      let skipped = 0;

      // 构建复合键范围
      let range: IDBKeyRange;
      if (options?.startTime && options?.endTime) {
        range = IDBKeyRange.bound([path, options.startTime], [path, options.endTime]);
      } else if (options?.startTime) {
        range = IDBKeyRange.bound([path, options.startTime], [path, Infinity]);
      } else if (options?.endTime) {
        range = IDBKeyRange.bound([path, -Infinity], [path, options.endTime]);
      } else {
        range = IDBKeyRange.bound([path, -Infinity], [path, Infinity]);
      }

      const direction = sortOrder === 'desc' ? 'prev' : 'next';
      let cursor = await index.openCursor(range, direction);

      while (cursor && results.length < limit) {
        if (skipped < skip) {
          skipped++;
        } else {
          results.push(cursor.value);
        }
        cursor = await cursor.continue();
        processed++;

        if (processed > (skip + limit) * 2) break;
      }

      return results;
    } else {
      // 回退到路径索引查询
      console.log('[VFS Storage] by-path-timestamp 索引不存在，使用 by-path 索引');
      return this.getChangesByPath(path, options, skip, limit, sortOrder);
    }
  }

  // 优化方法：使用路径索引查询特定文件
  private async getChangesByPath(
    path: string,
    options?: {
      startTime?: number;
      endTime?: number;
    },
    skip: number = 0,
    limit: number = 50,
    sortOrder: 'asc' | 'desc' = 'desc',
  ): Promise<FileChange<any>[]> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');
    const index = store.index('by-path');

    const allChanges = await index.getAll(path);

    // 应用时间过滤
    let filteredChanges = allChanges;
    if (options?.startTime || options?.endTime) {
      filteredChanges = allChanges.filter((change) => {
        if (options.startTime && change.timestamp < options.startTime) return false;
        if (options.endTime && change.timestamp > options.endTime) return false;
        return true;
      });
    }

    // 排序
    filteredChanges.sort((a, b) => {
      const order = sortOrder === 'desc' ? -1 : 1;
      return (a.timestamp - b.timestamp) * order;
    });

    // 分页
    return filteredChanges.slice(skip, skip + limit);
  }

  // 回退方法：原有逻辑但限制扫描数量
  private async getChangesLegacy(
    path?: string,
    options?: {
      startTime?: number;
      endTime?: number;
    },
    skip: number = 0,
    limit: number = 50,
    sortOrder: 'asc' | 'desc' = 'desc',
  ): Promise<FileChange<any>[]> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');
    const allChanges: FileChange<any>[] = [];

    let cursor = await store.openCursor();
    let processed = 0;
    const maxScan = 1000; // 限制最大扫描数量

    while (cursor && processed < maxScan) {
      const change = cursor.value as FileChange<any>;

      // 应用过滤条件
      if (path && change.path !== path) {
        cursor = await cursor.continue();
        processed++;
        continue;
      }

      if (options?.startTime && change.timestamp < options.startTime) {
        cursor = await cursor.continue();
        processed++;
        continue;
      }

      if (options?.endTime && change.timestamp > options.endTime) {
        cursor = await cursor.continue();
        processed++;
        continue;
      }

      allChanges.push(change);
      cursor = await cursor.continue();
      processed++;
    }

    // 排序和分页
    allChanges.sort((a, b) => {
      const order = sortOrder === 'desc' ? -1 : 1;
      return (a.timestamp - b.timestamp) * order;
    });
    return allChanges.slice(skip, skip + limit);
  }

  /**
   * 重建数据库以应用新索引（开发/测试用）
   * 注意：这会清空所有数据！
   */
  async rebuildDatabaseWithNewIndexes(): Promise<void> {
    if (!this.db) return;

    console.warn('[VFS Storage] 重建数据库 - 这将清空所有数据！');

    // 关闭当前数据库连接
    this.db.close();

    // 删除数据库
    await new Promise<void>((resolve, reject) => {
      const deleteReq = indexedDB.deleteDatabase(`vfs-${this.projectId}`);
      deleteReq.onsuccess = () => resolve();
      deleteReq.onerror = () => reject(deleteReq.error);
    });

    // 重新初始化
    await this.init(this.projectId);

    console.log('[VFS Storage] 数据库重建完成，新索引已生效');
  }

  /**
   * 检查当前数据库是否有新索引
   */
  async hasOptimizedIndexes(): Promise<boolean> {
    if (!this.db) return false;

    const tx = this.db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');

    return (
      store.indexNames.contains('by-timestamp') && store.indexNames.contains('by-path-timestamp')
    );
  }

  // 获取变更记录总数
  async getChangesCount(
    path?: string,
    options?: {
      startTime?: number;
      endTime?: number;
    },
  ): Promise<number> {
    const db = await this.getDB();
    const tx = db.transaction('changes', 'readonly');
    const store = tx.objectStore('changes');
    let count = 0;

    // 使用游标遍历记录
    let cursor = await store.openCursor();
    while (cursor) {
      const change = cursor.value as FileChange<any>;

      // 应用路径过滤
      if (path && change.path !== path) {
        cursor = await cursor.continue();
        continue;
      }

      // 应用时间范围过滤
      if (options?.startTime && change.timestamp < options.startTime) {
        cursor = await cursor.continue();
        continue;
      }
      if (options?.endTime && change.timestamp > options.endTime) {
        cursor = await cursor.continue();
        continue;
      }

      count++;
      cursor = await cursor.continue();
    }

    return count;
  }

  // 清理操作
  async clearHistory(path: string, beforeTimestamp: number): Promise<void> {
    const tx = this.db?.transaction(['versions', 'changes'], 'readwrite');

    // 删除旧版本
    const versionsIndex = tx?.objectStore('versions').index('by-path');
    const oldVersions = (await versionsIndex?.getAll(path)) || [];
    for (const version of oldVersions) {
      if (version.timestamp < beforeTimestamp && version.id) {
        await tx?.objectStore('versions').delete(Number(version.id));
      }
    }

    // 删除旧变更记录
    const changesIndex = tx?.objectStore('changes').index('by-path');
    const oldChanges = (await changesIndex?.getAll(path)) || [];
    for (const change of oldChanges) {
      if (change.timestamp < beforeTimestamp && change.id) {
        await tx?.objectStore('changes').delete(Number(change.id));
      }
    }

    await tx?.done;
  }

  // 批量操作
  async transaction<T>(
    stores: StoreNames<VFSSchema>[],
    mode: 'readonly' | 'readwrite',
    callback: (tx: IDBPTransaction<VFSSchema, StoreNames<VFSSchema>[], typeof mode>) => Promise<T>,
  ): Promise<T> {
    const db = await this.getDB();
    const tx = db.transaction(stores, mode);
    try {
      const result = await callback(tx);
      await tx.done;
      return result;
    } catch (error) {
      // 事务异常时会自动回滚，不需要手动 abort
      throw error;
    }
  }

  // 获取所有文件
  async getAllFiles(): Promise<FileSystemEntry[]> {
    if (!this.db) return [];

    const tx = this.db.transaction('files', 'readonly');
    try {
      const store = tx.objectStore('files');
      const index = store.index('by-project');

      // 使用 getAllKeys 和 getAll 来获取所有键和值
      const [keys, values] = await Promise.all([
        index.getAllKeys(this.projectId),
        index.getAll(this.projectId),
      ]);

      await tx.done;

      return values.map((file) => ({
        path: file.path.replace(`${this.projectId}:`, ''),
        content: file.content,
        stats: file.stats,
      }));
    } catch (error) {
      console.error('Error in getAllFiles:', error);
      // 事务异常时会自动回滚，不需要手动 abort
      throw error;
    }
  }

  private async getStore(storeName: 'files' | 'changes' | 'versions', mode: IDBTransactionMode) {
    return this.db?.transaction(storeName, mode).objectStore(storeName);
  }

  private async get(store: IDBObjectStore, key: string) {
    return store.get(key);
  }

  private async put(store: IDBObjectStore, value: any) {
    await store.put(value);
  }

  // 版本操作
  async addVersion(version: Omit<FileVersion, 'id'>): Promise<number> {
    const db = await this.getDB();
    const tx = db.transaction('versions', 'readwrite');
    const store = tx.objectStore('versions');
    const key = await store.add({
      ...version,
      projectId: this.projectId,
    });
    await tx.done;
    return Number(key);
  }

  // 分支管理
  // async createBranch(branch: LcBranch): Promise<void> {
  //   const db = await this.getDB();
  //   const tx = db.transaction('branches', 'readwrite');
  //   const store = tx.objectStore('branches');
  //   await store.add({
  //     ...branch,
  //     projectId: this.projectId,
  //   });
  //   await tx.done;
  // }

  // async getBranch(name: string): Promise<LcBranch | undefined> {
  //   const db = await this.getDB();
  //   return db.get('branches', name);
  // }

  // async getAllBranches(): Promise<LcBranch[]> {
  //   const db = await this.getDB();
  //   const tx = db.transaction('branches', 'readonly');
  //   const store = tx.objectStore('branches');
  //   const index = store.index('by-project');
  //   return index.getAll(this.projectId);
  // }

  // async updateBranch(branch: LcBranch): Promise<void> {
  //   const db = await this.getDB();
  //   const tx = db.transaction('branches', 'readwrite');
  //   const store = tx.objectStore('branches');
  //   await store.put({
  //     ...branch,
  //     projectId: this.projectId,
  //   });
  //   await tx.done;
  // }

  // async deleteBranch(name: string): Promise<void> {
  //   const db = await this.getDB();
  //   const tx = db.transaction(['branches', 'commits'], 'readwrite');

  //   // 删除分支
  //   await tx.objectStore('branches').delete(name);

  //   // 删除分支下的所有提交
  //   const commitsIndex = tx.objectStore('commits').index('by-branch');
  //   const commits = await commitsIndex.getAll(name);
  //   for (const commit of commits) {
  //     await tx.objectStore('commits').delete(commit.id);
  //   }

  //   await tx.done;
  // }

  // // 提交管理
  // async createCommit(commit: LcCommit): Promise<void> {
  //   const db = await this.getDB();
  //   const tx = db.transaction(['commits', 'branches'], 'readwrite');

  //   // 保存提交
  //   await tx.objectStore('commits').add(commit);

  //   // 更新分支的最后提交
  //   const branch = await this.getBranch(commit.branch);
  //   if (branch) {
  //     await tx.objectStore('branches').put({
  //       ...branch,
  //       latestCommitId: commit.id,
  //     });
  //   }

  //   await tx.done;
  // }

  // async getCommit(id: string): Promise<LcCommit | undefined> {
  //   const db = await this.getDB();
  //   return db.get('commits', id);
  // }

  // async getCommitsByBranch(branchName: string): Promise<LcCommit[]> {
  //   const db = await this.getDB();
  //   const tx = db.transaction('commits', 'readonly');
  //   const store = tx.objectStore('commits');
  //   const index = store.index('by-branch');
  //   return index.getAll(branchName);
  // }

  async getFilesByPath(path: string, recursive: boolean = false): Promise<FileSystemEntry[]> {
    const startTime = performance.now();
    // console.log(`[VFS Storage] 开始查询文件，路径: ${path}, 递归模式: ${recursive}`);

    const db = await this.getDB();
    const tx = db.transaction('files', 'readonly');
    const store = tx.objectStore('files');
    const index = store.index('by-project');

    const dbQueryStartTime = performance.now();
    const allFiles = await index.getAll(this.projectId);
    const dbQueryEndTime = performance.now();
    // console.log(
    //   `[VFS Storage] 数据库查询完成，获取到 ${allFiles.length} 个文件，耗时: ${(
    //     dbQueryEndTime - dbQueryStartTime
    //   ).toFixed(2)}ms`,
    // );

    // 标准化路径，确保以 / 开头
    const normalizedPath = path.startsWith('/') ? path : `/${path}`;
    // console.log(`[VFS Storage] 标准化路径: ${normalizedPath}`);

    const filterStartTime = performance.now();
    const filteredFiles = allFiles.filter((file) => {
      const filePath = file.path;
      const normalizedFilePath = filePath.replace(`${this.projectId}:`, '');
      // console.log(`[VFS Storage] 处理文件: ${normalizedFilePath}`);

      // 如果是根路径
      // if (normalizedPath === '/') {
      //   if (recursive) {
      //     // 递归模式返回所有文件
      //     return true;
      //   } else {
      //     // 非递归模式只返回根目录下的直接子项
      //     const pathParts = normalizedFilePath.split('/').filter(Boolean);
      //     const isDirectChild = pathParts.length === 1;
      //     console.log(
      //       `[VFS Storage] 根目录文件 ${normalizedFilePath} ${
      //         isDirectChild ? '是' : '不是'
      //       }直接子项`,
      //     );
      //     return isDirectChild;
      //   }
      // }

      // 如果是其他路径
      if (recursive) {
        // 递归模式：返回当前目录及其所有子目录下的文件
        const isInSubDir = normalizedFilePath.startsWith(
          normalizedPath === '/' ? '/' : `${normalizedPath}/`,
        );
        if (isInSubDir) {
          // 确保文件在目标目录或其子目录中
          const relativePath = normalizedFilePath.slice(normalizedPath.length + 1);
          // console.log(
          //   `[VFS Storage] 文件 ${normalizedFilePath} 在目标目录或其子目录中，相对路径: ${relativePath}`,
          // );
          return true;
        }
        // console.log(`[VFS Storage] 文件 ${normalizedFilePath} 不在目标目录或其子目录中`);
        return false;
      } else {
        // 非递归模式：只返回当前目录下的直接子项
        const parentDir = normalizedPath === '/' ? '/' : `${normalizedPath}/`;
        const relativePath = normalizedFilePath.slice(parentDir.length);
        const isDirectChild =
          normalizedFilePath.startsWith(parentDir) && !relativePath.includes('/');
        // console.log(
        //   `[VFS Storage] 文件 ${normalizedFilePath} ${
        //     isDirectChild ? '是' : '不是'
        //   }目标目录的直接子项`,
        // );
        return isDirectChild;
      }
    });

    // const filterEndTime = performance.now();
    // console.log(
    //   `[VFS Storage] 文件过滤完成，过滤后剩余 ${filteredFiles.length} 个文件，过滤耗时: ${(
    //     filterEndTime - filterStartTime
    //   ).toFixed(2)}ms`,
    // );

    const result = filteredFiles.map((file) => ({
      path: file.path.replace(`${this.projectId}:`, ''),
      content: file.content,
      stats: file.stats,
    }));

    // const endTime = performance.now();
    // console.log(
    //   `[VFS Storage] 文件查询完成，总耗时: ${(endTime - startTime).toFixed(2)}ms，返回 ${
    //     result.length
    //   } 个文件`,
    // );

    return result;
  }

  async initGlobalDB() {
    if (this.globalDb) return;

    this.globalDb = await openDB<GlobalSchema>('global-resources', 1, {
      upgrade(db) {
        const scriptsStore = db.createObjectStore('scripts', { keyPath: 'url' });
        scriptsStore.createIndex('by-url', 'url');
      },
    });
  }

  async getScript(url: string): Promise<ScriptResource | null> {
    await this.initGlobalDB();
    if (!this.globalDb) return null;

    // 先检查内存缓存
    if (this.scriptCache.has(url)) {
      return this.scriptCache.get(url)!;
    }

    // 从 IndexedDB 获取
    const script = await this.globalDb.get('scripts', url);
    if (script) {
      this.scriptCache.set(url, script);
      return script;
    }

    return null;
  }

  async saveScript(
    url: string,
    content: string,
    options: { version?: string; dependencies?: string[] } = {},
  ) {
    await this.initGlobalDB();
    if (!this.globalDb) return;

    const script: ScriptResource = {
      url,
      content,
      lastLoadTime: Date.now(),
      version: options.version,
      dependencies: options.dependencies,
    };

    await this.globalDb.put('scripts', script);
    this.scriptCache.set(url, script);
  }

  async loadScript(
    url: string,
    options: {
      forceReload?: boolean;
      timeout?: number;
      retries?: number;
    } = {},
  ): Promise<void> {
    const { forceReload = false, timeout = 10000, retries = 3 } = options;

    // 如果不是强制重载，先检查缓存
    if (!forceReload) {
      const cachedScript = await this.getScript(url);
      if (cachedScript) {
        // 检查是否需要更新（比如版本变化）
        if (cachedScript.version) {
          // 这里可以添加版本检查逻辑
        }
        return;
      }
    }

    // 加载脚本
    const script = await this.fetchScript(url, timeout, retries);
    if (script) {
      await this.saveScript(url, script);
    }
  }

  private async fetchScript(url: string, timeout: number, retries: number): Promise<string | null> {
    let lastError: Error | null = null;

    for (let i = 0; i < retries; i++) {
      try {
        const response: any = await Promise.race([
          fetch(url),
          new Promise((_, reject) => setTimeout(() => reject(new Error('加载超时')), timeout)),
        ]);

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        return await response.text();
      } catch (error) {
        lastError = error as Error;
        console.warn(`脚本加载失败，尝试重试 ${i + 1}/${retries}:`, error);
        if (i < retries - 1) {
          await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
        }
      }
    }

    console.error(`脚本加载失败: ${url}`, lastError);
    return null;
  }

  async clearScriptCache(url?: string) {
    await this.initGlobalDB();
    if (!this.globalDb) return;

    if (url) {
      await this.globalDb.delete('scripts', url);
      this.scriptCache.delete(url);
    } else {
      await this.globalDb.clear('scripts');
      this.scriptCache.clear();
    }
  }

  // 获取脚本加载状态
  async getScriptStatus(url: string): Promise<{
    isLoaded: boolean;
    lastLoadTime?: number;
    version?: string;
    dependencies?: string[];
  }> {
    const script = await this.getScript(url);
    return {
      isLoaded: !!script,
      lastLoadTime: script?.lastLoadTime,
      version: script?.version,
      dependencies: script?.dependencies,
    };
  }

  // 通过id获取单条变更记录
  async getChangeById(id: number): Promise<FileChange<any> | undefined> {
    const db = await this.getDB();
    return db.get('changes', id);
  }

  // KV 存储（用于存储脏文件集合等元数据）
  async getKV(key: string): Promise<string | undefined> {
    if (!this.db) return undefined;
    const entry = await this.db.get('files', this.getFileKey(key));
    if (entry && typeof entry.content === 'string') {
      return entry.content;
    }
    return undefined;
  }

  async setKV(key: string, value: string): Promise<void> {
    if (!this.db) return;
    const entry = {
      projectId: this.projectId,
      path: this.getFileKey(key),
      content: value,
      stats: {
        type: 'file' as const,
        size: value.length,
        createTime: Date.now(),
        modifyTime: Date.now(),
      },
    };
    await this.db.put('files', entry);
  }

  // 文件系统版本管理
  async getFSVersion(): Promise<number> {
    if (!this.db) return 1; // 默认版本 1

    try {
      const tx = this.db.transaction('fsVersions', 'readonly');
      const store = tx.objectStore('fsVersions');
      const versionInfo = await store.get(this.projectId);
      await tx.done;
      return versionInfo?.version || 1;
    } catch (error) {
      console.error('[VFS Storage] 获取文件系统版本失败:', error);
      return 1; // 出错时返回默认版本
    }
  }

  async setFSVersion(version: number): Promise<void> {
    if (!this.db) return;

    const currentVersion = await this.getFSVersion();
    const versionInfo = {
      projectId: this.projectId,
      version,
      upgradeTime: Date.now(),
      previousVersion: currentVersion !== version ? currentVersion : undefined,
    };

    try {
      const tx = this.db.transaction('fsVersions', 'readwrite');
      const store = tx.objectStore('fsVersions');
      await store.put(versionInfo);
      await tx.done;
      console.log(`[VFS Storage] 文件系统版本更新: ${currentVersion} -> ${version}`);
    } catch (error) {
      console.error('[VFS Storage] 设置文件系统版本失败:', error);
      throw error;
    }
  }

  /**
   * JSX到TSX迁移：删除所有JSX文件
   */
  async migrateJsxToTsx(): Promise<{ deletedCount: number }> {
    if (!this.db) return { deletedCount: 0 };

    let deletedCount = 0;

    try {
      const tx = this.db.transaction('files', 'readwrite');
      const store = tx.objectStore('files');
      const index = store.index('by-project');

      // 获取所有文件
      const files = await index.getAll(this.projectId);

      for (const file of files) {
        const filePath = file.path.replace(`${this.projectId}:`, '');

        // 检查是否是JSX文件
        if (filePath.endsWith('.tsx')) {
          console.log(`[VFS Storage] 删除JSX文件: ${filePath}`);
          await store.delete(file.path);
          deletedCount++;
        }
      }

      await tx.done;
      console.log(`[VFS Storage] JSX到TSX迁移完成: 删除了 ${deletedCount} 个JSX文件`);

      return { deletedCount };
    } catch (error) {
      console.error('[VFS Storage] JSX到TSX迁移失败:', error);
      throw error;
    }
  }

  async needsUpgrade(): Promise<{
    needsUpgrade: boolean;
    currentVersion: number;
    targetVersion: number;
  }> {
    const currentVersion = await this.getFSVersion();
    const targetVersion = 4; // 路径结构迁移版本

    return {
      needsUpgrade: currentVersion < targetVersion,
      currentVersion,
      targetVersion,
    };
  }

  // 清理旧格式文件（版本 1 -> 版本 2 的升级逻辑）
  async cleanupOldFormatFiles(): Promise<{ deletedCount: number; keptCount: number }> {
    if (!this.db) return { deletedCount: 0, keptCount: 0 };

    console.log('[VFS Storage] 开始清理旧格式文件...');

    const allFiles = await this.getAllFiles();
    let deletedCount = 0;
    let keptCount = 0;

    const tx = this.db.transaction('files', 'readwrite');

    for (const file of allFiles) {
      const fileName = file.path.split('/').pop() || '';
      const fileNameParts = fileName.split('.');

      // 检查是否是旧格式文件名（包含中文描述）
      if (fileNameParts.length >= 3) {
        const possibleDesc = fileNameParts[0];

        // 如果第一部分包含中文字符，认为是旧格式，需要删除
        if (/[\u4e00-\u9fff]/.test(possibleDesc)) {
          console.log(`[VFS Storage] 删除旧格式文件: ${file.path}`);
          await tx.store.delete(this.getFileKey(file.path));
          deletedCount++;
        } else {
          keptCount++;
        }
      } else {
        keptCount++;
      }
    }

    await tx.done;

    console.log(
      `[VFS Storage] 清理完成: 删除 ${deletedCount} 个旧格式文件，保留 ${keptCount} 个文件`,
    );

    return { deletedCount, keptCount };
  }
}
